﻿using System;
using System.Collections.Generic;
using System.Threading;
using NUnit.Framework;
using ShuttleBus;
using ShuttleBus.AdminMessages;
using ShuttleBus.Transports.Msmq;

namespace Tests.Integration.Msmq
{
    [Explicit("Integration tests should be executed directly")]
    [TestFixture]
    public class PublishingAMessageSendsToAllSubscribers : IHandle<MyMessage>, IHandle<OtherMessage>
    {
        private IBus _bus;
        private static int _handledCount = 0;
        private static object _lock = new object();

        [SetUp]
        public void Setup()
        {
            var subscription = new Subscription(new Uri("msmq://localhost/test_queue"), typeof(MyMessage));
            var subscription2 = new Subscription(new Uri("msmq://localhost/test_queue"), typeof(OtherMessage));

            _bus = Bus.Configure()
                .ForMsmq(1, 600, new Uri("msmq://localhost/test_queue"))
                .WithSubscriptionsTo(a =>
                                         {
                                             a.Add(subscription);
                                             a.Add(subscription2);
                                         })
                .Start();
        }

        [Test]
        public void RecievesAddSubscriptionEventAndAddsSubscription()
        {
            var messages = new List<Message>();
            for (var i = 0; i < 0; i++)
            {
                if (i % 2 == 0)
                {
                    messages.Add(new MyMessage());
                }
                else
                {
                    messages.Add(new OtherMessage());
                }
            }

            int sentCount = 0;

            messages.ForEach(m =>
                                 {
                                     if (m is OtherMessage)
                                     {
                                         Console.WriteLine("Published OtherMessage: {0}", ((OtherMessage)m).Id);
                                     }
                                     else
                                     {
                                         Console.WriteLine("Published MyMessage: {0}", ((MyMessage)m).Id);
                                     }
                                     sentCount++;
                                     _bus.Publish(m);
                                 });

            Thread.Sleep(150000);

            Assert.AreEqual(sentCount, _handledCount, "Should have handled the same number of messages sent");
        }

        public void Handle(MyMessage message)
        {
            Console.WriteLine("PublishingAMessageSendsToAllSubscribers Test Handled MyMessage: {0} on Thread: {1}", message.Id, Thread.CurrentThread.Name);

            lock (_lock)
            {
                _handledCount++;
            }
        }

        public void Handle(OtherMessage message)
        {
            Console.WriteLine("Test Handled OtherMessage: {0}", message.Id);
            lock (_lock)
            {
                _handledCount++;
            }
        }

    }
}